package em.ctrl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import com.alibaba.fastjson.JSONObject;

import em.job.ConnServer;
import em.program.imp.OtherData;
import em.util.TermUtil;
import base.ctrl.BaseController;
import base.jfinal.anatation.RouteBind;
import base.util.PropertiesContent;
import em.util.ConstUtil;
@RouteBind(path="termUpData")
public class TermUpDataCtrl extends BaseController{
	private static BlockingQueue<String> messQueue=new LinkedBlockingQueue<String>(100);
	public void SingleUpData() throws InterruptedException{
		String FileName=this.getPara("FileName");
		String url=PropertiesContent.get("updata_term_URL");
		String termCode=this.getPara("TermCode");
		Integer TNUM=TermUtil.TermCodeXOR(termCode);
		double prog=0;//升级完成进度
		File file = new File(url+ConstUtil.UPDATA_TERM_URL+FileName);
		//判断升级包是否有效
		if(file.exists()){
			messQueue.clear();
			messQueue.put("获取升级文件信息:"+file.getName());
			log.debug("获取升级文件信息:"+file.getName());
			//查询待升级终端版本信息
			messQueue.put("查询终端版本信息:"+termCode);
			log.debug("查询终端版本信息:"+termCode);
			if(ConnServer.getInstance().isConn()==false){
				messQueue.put("采集服务器未就绪,升级结束");
				renderJson("{\"PROG\":0}");
			}
			String result= OtherData.getInstance().getTermVersion(TNUM.toString());
			JSONObject json=JSONObject.parseObject(result);
			log.debug(termCode+"回应:"+result);
			//返回结果有err代表查询失败
			if(json.containsKey("SVER")){
				messQueue.put(termCode+"回应版本为:"+json.getString("SVER"));
				String HVER=json.getString("HVER");
				String NSVER=FileName.substring(0,FileName.lastIndexOf("."));
				byte[] upData = readTobytes(file);
				messQueue.put("开始升级终端:"+termCode);
				log.debug("开始升级终端:"+termCode);
				prog=UpDataPractice(termCode, HVER, NSVER, upData,prog,true);
				renderJson("{\"PROG\":"+prog+"}");//升级最后结果
			}else{
				messQueue.put("终端回应:"+json.getIntValue("err")+"(4:终端不在线;6:代表终端忙;8:终端回复超时)");
				messQueue.put("本次升级结束");
				renderJson("{\"PROG\":"+prog+"}");
			}
		}else{
			messQueue.put("升级文件不存在,本次升级结束");
			renderJson("{\"PROG\":"+prog+"}");//升级包不存在
		}
	}
	/**
	 * 升级流程
	 * 1.发送升级包信息
	 * 2.发送升级数据
	 * @param HVER
	 * @param NSVER
	 * @param upData
	 * @param iFlag true:需要记录单个日志,false:不需要记录
	 * @return 升级进度0~100(表示完成);
	 * @throws InterruptedException 
	 */
	public double UpDataPractice(String termCode,String HVER,String NSVER,byte[] upData,double prog,boolean iFlag) throws InterruptedException{
		int count=1;
		Integer TNUM=TermUtil.TermCodeXOR(termCode);
		do{
			//发送升级包信息,获取终端回应是否升级
			if(iFlag) {
				messQueue.put("第" + count + "次升级开始....");
				messQueue.put("升级终端---发送升级包信息至" + termCode + "......");
				log.debug("升级终端---发送升级包信息至" + termCode + "......");
			}
			String TermVersion=OtherData.getInstance().sendUpDataVersionInfo(TNUM, HVER, NSVER, upData);
			JSONObject json=JSONObject.parseObject(TermVersion);
			if(iFlag) {
				log.debug("升级终端---" + termCode + "回应:" + TermVersion);
				messQueue.put("升级终端---" + termCode + "回应......");
			}
			if(json.containsKey("FPOS")){
				//终端回应升级,给出升级包数据地址
				int FPOS=json.getIntValue("FPOS");
				int err=1;
				//发送升级数据开始升级,获取终端升级结果回复
				if (iFlag) {
					log.debug("升级终端---" + termCode + "发送升级包");
					messQueue.put("升级终端---" + termCode + "发送升级包");
				}
				while(err==1){
					String termReq=OtherData.getInstance().sendTermUpdateData(TNUM, HVER, NSVER, upData, FPOS,1024);
					JSONObject termReqJson=JSONObject.parseObject(termReq);
					switch (termReqJson.getIntValue("err")) {
					case 1:
						FPOS=termReqJson.getIntValue("FPOS");
						if(iFlag) {
							log.debug("升级终端---" + termCode + "发送完成" + prog + "%.....");
							messQueue.put("升级终端---" + termCode + "发送完成" + prog + "%.....");
						}
						break;
					case 2://终端升级完成
						err=2;
						count=7;
						if(iFlag) {
							log.debug("升级终端---" + termCode + "发送完成" + prog + "%.....");
							messQueue.put("升级终端---" + termCode + "完成100%.....升级结束");
						}
						break;
						//4:升级终止,6:终端忙:,-1 8:终端回复超时
					case -1:
					case 4:
					case 6:
					case 8:
						err=termReqJson.getIntValue("err");
						if(iFlag) {
							log.debug("终端回应:" + err + "(-1:获取终端数据超时;4:终止;6:终端忙;8:超时).....失败准备再次尝试..;已完成" + prog + "%");
							messQueue.put("终端回应:" + err + "(-1:获取终端数据超时;4:终止;6:终端忙;8:超时).....失败准备再次尝试..;已完成" + prog + "%");
						}
						count++;
						break;
					}
					prog=termReqJson.getBigDecimal("PROG").doubleValue();
					
				}
			}else{
				if(iFlag) {
					log.debug("升级终端---" + termCode + "失败,重试第" + count + "次....");
					messQueue.put("升级终端---" + termCode + "失败,重试第" + count + "次....");
				}
				count++;
			}
		}while(count<6);
		if(count>=5){
			if(iFlag) {
				log.debug("本次升级终端未完成,升级结束");
				messQueue.put("本次升级终端未完成,升级结束");
			}
		}
		return prog;
		}
	public void rendMessage(){
		String message;
		try {
			log.debug("查询消息队列....");
			message=messQueue.take();
		} catch (InterruptedException e) {
			e.printStackTrace();
			message="读取消息失败....";
		}
		renderJson("{\"mess\":\""+message+"\"}");
	}
	public static byte[] readTobytes(File file) {
		Long filelength = file.length(); // 获取文件长度
		byte[] filecontent = new byte[filelength.intValue()];
		try {
			FileInputStream in = new FileInputStream(file);
			in.read(filecontent);
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return filecontent;// 返回文件内容,默认编码
	}
}
